🎖️GitЯра🎖️
src/helpers/sensors/RAK12035_SoilMoisture.cpp 93b2db63de9009af047a2d0e1bcd97b4b0ba7106 (93b2db63) Text, 22.64 KB
T8b949e/*----------------------------------------------------------------------*
* RAK12035_SoilMoistureSensor.cpp - Arduino library for the Sensor *
* version of I2C Soil Moisture Sensor version from Chrirp *
* (https://github.com/Miceuz/i2c-moisture-sensor). *
* *
* Ingo Fischer 11Nov2015 *
* https://github.com/Apollon77/I2CSoilMoistureSensor *
* *
* Ken Privitt 8Feb2026 *
* Adapted for MeshCore Firmware Stack *
* *
* MIT license *
* *
* This file contains a collection of routines to access the *
* RAK12035 Soil Moisture Sensor via I2C. The sensor provides *
* Soil Temperature and capacitance-based Soil Moisture Readings. *
* *
*----------------------------------------------------------------------*/
Tff7b72#Tff7b72include T8b949e"RAK12035_SoilMoisture.h"
Tff7b72#Tff7b72include T8b949e"MeshCore.h"
Tff7b72#Tff7b72include T8b949e<Wire.h>
T8b949e/*----------------------------------------------------------------------*
* Constructor. *
*----------------------------------------------------------------------*/
T8b949e// RAK12035_SoilMoisture(uint8_t addr)
T8b949e//
T8b949e// Accepts the I2C Address to look for the RAK12035
T8b949e// Initializes the I2C to null (will be setup later in Wire.Begin()
T8b949e//
T8b949e// No hardware is touched in the constructor.
T8b949e// I2C communication is deferred until begin() is called.
T8b949e//------------------------------------------------------------------------------
Te6edf3RAK12035_SoilMoistureTff7b72:Tff7b72:Te6edf3RAK12035_SoilMoistureTb4b4b4(Tffa657uint8_t Te6edf3addrTb4b4b4)
Tb4b4b4{
Te6edf3_addr Tff7b72= Te6edf3addrTb4b4b4; T8b949e// Save the sensor's I2C address
Te6edf3_i2c Tff7b72= Tffa657nullptrTb4b4b4; T8b949e// Bus not assigned yet; must be set in begin()
Tb4b4b4}
T8b949e//------------------------------------------------------------------------------
T8b949e// setup()
T8b949e//------------------------------------------------------------------------------
T8b949e// setup(TwoWire &i2c)
T8b949e//
T8b949e// Assigns the I2C bus that this driver instance will use. This allows the
T8b949e// application to choose between Wire, Wire1, or any other TwoWire instance
T8b949e// supported by the platform.
T8b949e//
T8b949e// No I2C communication occurs here; setup() simply stores the pointer so that
T8b949e// begin() and all register‑level operations know which bus to use.
T8b949e//------------------------------------------------------------------------------
Tffa657void Te6edf3RAK12035_SoilMoistureTff7b72:Tff7b72:Te6edf3setupTb4b4b4(Te6edf3TwoWire Tff7b72&Te6edf3i2cTb4b4b4)
Tb4b4b4{
Te6edf3_i2c Tff7b72= Tff7b72&Te6edf3i2cTb4b4b4; T8b949e// assigns the bus pointer
Te6edf3_i2cTff7b72-Tff7b72>Te6edf3beginTb4b4b4(Tb4b4b4)Tb4b4b4; T8b949e// Initialize the bus to Wire or Wire1
Tb4b4b4}
T8b949e//------------------------------------------------------------------------------
T8b949e// RAK12035 Soil Moisture begin()
T8b949e//------------------------------------------------------------------------------
T8b949e//
T8b949e// Performs initialization of the RAK12035 soil‑moisture sensor. This
T8b949e// routine assumes that the application has already selected the I2C bus via
T8b949e// setup() and that the bus has been initialized externally (Wire.begin()).
T8b949e// It uses the passed in I2C Address (default 0x20)
T8b949e//
T8b949e// *** This code does not support three sensors ***
T8b949e// The RAK12023 has three connectors, but each of the sensors attached must
T8b949e// all have different I2C addresses.
T8b949e// This code has a function to set the I2C address of a sensor
T8b949e// and currently only supports one address 0x20 (the default).
T8b949e// To support three sensors, EnvironmentSensorManager would need to be modified
T8b949e// to support multiple instances of the RAK12035_SoilMoisture class,
T8b949e// each with a different address. (0x20, 0x21, 0x22)
T8b949e// The begin() function would need to be modified to loop through the three addresses
T8b949e//
T8b949e// DEBUG STATEMENTS: Can be enabled by uncommenting or adding:
T8b949e// File: variants/rak4631 platformio.ini
T8b949e// Section example: [env:RAK_4631_companion_radio_ble]
T8b949e// Enable Debug statements: -D MESH_DEBUG=1
T8b949e//
T8b949e//------------------------------------------------------------------------------
Tffa657bool Te6edf3RAK12035_SoilMoistureTff7b72:Tff7b72:Te6edf3beginTb4b4b4(Tffa657uint8_t Te6edf3addrTb4b4b4)
Tb4b4b4{
T8b949e// MESH_DEBUG_PRINTLN("begin() - Start of RAK12035 initialization");
T8b949e// MESH_DEBUG_PRINTLN("begin() - RAK12035 passed in Address %02X", addr);
T8b949e// 1. Ensure setup() was called
Tff7b72if Tb4b4b4(Te6edf3_i2c Tff7b72=Tff7b72= Tffa657nullptrTb4b4b4) Tb4b4b4{
Te6edf3MESH_DEBUG_PRINTLNTb4b4b4(Ta5d6ff"Ta5d6ffRAK12035 ERROR: I2C bus not set!Ta5d6ff"Tb4b4b4)Tb4b4b4;
Tff7b72return Tffa657falseTb4b4b4;
Tb4b4b4}
Tffa657uint16_t Te6edf3_dry_cal Tff7b72= T79c0ff200Tb4b4b4;
Tffa657uint16_t Te6edf3_wet_cal Tff7b72= T79c0ff600Tb4b4b4;
Tffa657uint8_t Te6edf3_version Tff7b72= T79c0ff0Tb4b4b4;
Tffa657uint8_t Te6edf3_addrTb4b4b4; T8b949e// The I2C address to be used (passed in parameter)
T8b949e/*------------------------------------------------------------------------------------------
* Set Calibration values - This is done with custom a firmware version
*
* USE the Build Flag: -D ENABLE_RAK12035_CALIBRATION = 1
* OR
* Change the value to 1 in the RAK12035_SoilMoisture.h file
*
* Calibration Procedure:
* 1) Flash the Calibration version of the firmware.
* 2) Leave the sensor dry, power up the device.
* 3) After detecting the RAK12035 this firmware will display calibration data on Channel 3
*
* Frequency = Current Capacitance Value
* Temperature = Current Wet calibration value
* Power = Current Dry calibration value
*
* 4) Click refresh several times. This will take a capacitance reading and if it is
* greater than the current Dry value it will store it in the sensor
* The value will bounce a little as you click refresh, but it eventually settles down (a few clicks)
* the stored value will stabalize at it's Maximum value.
*
* 5) Put the sensor in water.
*
* 6) Click refresh several times. This will take a capacitance reading and if it is
* less than the current Wet value it will store it in the sensor
* The value will bounce a little as you click refresh, but it eventually settles down (a few clicks)
* the stored value will stabalize at it's Minimum value.
*
* 7) The Sensor is now calibrated, turn off the device.
*
* 8) Reflash the device with the non-Calibration Firmware, Data will be shown on Channel 2
*
*------------------------------------------------------------------------------------------
*/
Tff7b72#Tff7b72if ENABLE_RAK12035_CALIBRATION
Tffa657uint16_t Te6edf3_wet Tff7b72= T79c0ff2000Tb4b4b4; T8b949e// A high value the should be out of the normal Wet range
Te6edf3set_humidity_fullTb4b4b4(Te6edf3_wetTb4b4b4)Tb4b4b4;
Tffa657uint16_t Te6edf3_dry Tff7b72= T79c0ff50Tb4b4b4; T8b949e// A low value the should be out of the normal Dry range
Te6edf3set_humidity_zeroTb4b4b4(Te6edf3_dryTb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72endif
T8b949e/*--------------------------------------------------------------------------------
*
* Check if a sensor is present and return true if found, false if not present
*
*--------------------------------------------------------------------------------
*/
Tff7b72if Tb4b4b4(Te6edf3query_sensorTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3MESH_DEBUG_PRINTLNTb4b4b4(Ta5d6ff"Ta5d6ffbegin() - Sensor responded with valid versionTa5d6ff"Tb4b4b4)Tb4b4b4;
Tff7b72return Tffa657trueTb4b4b4;
Tb4b4b4}
Tff7b72else Tb4b4b4{
Te6edf3MESH_DEBUG_PRINTLNTb4b4b4(Ta5d6ff"Ta5d6ffbegin() - Sensor version FAILTa5d6ff"Tb4b4b4)Tb4b4b4;
Tff7b72return Tffa657falseTb4b4b4;
Tb4b4b4}
Tb4b4b4}
T8b949e/*---------------------------------------------------------------------------------
*
* Below are all the routines to execute the various I2C commands supported
* by the RAK12035 sensor
*
*--------------------------------------------------------------------------------*/
Tffa657uint16_t Te6edf3RAK12035_SoilMoistureTff7b72:Tff7b72:Te6edf3get_sensor_capacitanceTb4b4b4(Tb4b4b4) T8b949e//Command 01 - (r) 2 byte
Tb4b4b4{
Tffa657uint8_t Te6edf3bufTb4b4b4[T79c0ff2Tb4b4b4] Tff7b72= Tb4b4b4{T79c0ff0Tb4b4b4}Tb4b4b4;
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3read_rak12035Tb4b4b4(Te6edf3SOILMOISTURESENSOR_GET_CAPACITANCETb4b4b4, Te6edf3bufTb4b4b4, T79c0ff2Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3MESH_DEBUG_PRINTLNTb4b4b4(Ta5d6ff"Ta5d6ffFunction 1: get_capacitance() FAIL: Bad data returned = %02X %02XTa5d6ff"Tb4b4b4, Te6edf3bufTb4b4b4[T79c0ff0Tb4b4b4]Tb4b4b4, Te6edf3bufTb4b4b4[T79c0ff1Tb4b4b4]Tb4b4b4)Tb4b4b4;
Tff7b72return Tb4b4b4(Te6edf3bufTb4b4b4[T79c0ff0Tb4b4b4] Tff7b72<Tff7b72< T79c0ff8Tb4b4b4) Tff7b72| Te6edf3bufTb4b4b4[T79c0ff1Tb4b4b4]Tb4b4b4; T8b949e// return raw for debugging
Tb4b4b4}
Tffa657uint16_t Te6edf3cap Tff7b72= Tb4b4b4(Te6edf3bufTb4b4b4[T79c0ff0Tb4b4b4] Tff7b72<Tff7b72< T79c0ff8Tb4b4b4) Tff7b72| Te6edf3bufTb4b4b4[T79c0ff1Tb4b4b4]Tb4b4b4;
Te6edf3MESH_DEBUG_PRINTLNTb4b4b4(Ta5d6ff"Ta5d6ffFunction 1: get_capacitance() SUCCESS: Capacitance = %dTa5d6ff"Tb4b4b4, Te6edf3capTb4b4b4)Tb4b4b4;
Tff7b72return Te6edf3capTb4b4b4;
Tb4b4b4}
Tffa657uint8_t Te6edf3RAK12035_SoilMoistureTff7b72:Tff7b72:Te6edf3get_I2C_addressTb4b4b4(Tb4b4b4) T8b949e//Command 02 - (r) 1 byte
Tb4b4b4{
Tffa657uint8_t Te6edf3addr Tff7b72= T79c0ff0Tb4b4b4;
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3read_rak12035Tb4b4b4(Te6edf3SOILMOISTURESENSOR_GET_I2C_ADDRTb4b4b4, Tff7b72&Te6edf3addrTb4b4b4, T79c0ff1Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3MESH_DEBUG_PRINTLNTb4b4b4(Ta5d6ff"Ta5d6ffFunction 2: get_I2C_address() FAIL: Bad data returned = %02XTa5d6ff"Tb4b4b4, Te6edf3addrTb4b4b4)Tb4b4b4;
Tff7b72return Te6edf3addrTb4b4b4; T8b949e// return raw for debugging
Tb4b4b4}
Te6edf3MESH_DEBUG_PRINTLNTb4b4b4(Ta5d6ff"Ta5d6ffFunction 2: get_I2C_address() SUCCESS: I2C Address = %02XTa5d6ff"Tb4b4b4, Te6edf3addrTb4b4b4)Tb4b4b4;
Tff7b72return Te6edf3addrTb4b4b4;
Tb4b4b4}
Tffa657bool Te6edf3RAK12035_SoilMoistureTff7b72:Tff7b72:Te6edf3set_sensor_addrTb4b4b4(Tffa657uint8_t Te6edf3addrTb4b4b4) T8b949e//Command 03 - (w) 1 byte
Tb4b4b4{
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3write_rak12035Tb4b4b4(Te6edf3SOILMOISTURESENSOR_SET_I2C_ADDRTb4b4b4, Tff7b72&Te6edf3addrTb4b4b4, T79c0ff1Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3MESH_DEBUG_PRINTLNTb4b4b4(Ta5d6ff"Ta5d6ffFunction 3: set_I2C_address() FAIL: Could not set new address %02XTa5d6ff"Tb4b4b4, Te6edf3addrTb4b4b4)Tb4b4b4;
Tff7b72return Tffa657falseTb4b4b4;
Tb4b4b4}
Te6edf3MESH_DEBUG_PRINTLNTb4b4b4(Ta5d6ff"Ta5d6ffFunction 3: set_I2C_address() SUCCESS: New address = %02XTa5d6ff"Tb4b4b4, Te6edf3addrTb4b4b4)Tb4b4b4;
Tff7b72return Tffa657trueTb4b4b4;
Tb4b4b4}
Tffa657uint8_t Te6edf3RAK12035_SoilMoistureTff7b72:Tff7b72:Te6edf3get_sensor_versionTb4b4b4(Tb4b4b4) T8b949e// Command 04 - 1 byte
Tb4b4b4{
Tffa657uint8_t Te6edf3v Tff7b72= T79c0ff0Tb4b4b4;
Te6edf3read_rak12035Tb4b4b4(Te6edf3SOILMOISTURESENSOR_GET_VERSIONTb4b4b4, Tff7b72&Te6edf3vTb4b4b4, T79c0ff1Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3read_rak12035Tb4b4b4(Te6edf3SOILMOISTURESENSOR_GET_VERSIONTb4b4b4, Tff7b72&Te6edf3vTb4b4b4, T79c0ff1Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3MESH_DEBUG_PRINTLNTb4b4b4(Ta5d6ff"Ta5d6ffFunction 4: get_sensor_version() FAIL: Bad data returned = %02XTa5d6ff"Tb4b4b4, Te6edf3vTb4b4b4)Tb4b4b4;
Tff7b72return Te6edf3vTb4b4b4;
Tb4b4b4}
Te6edf3MESH_DEBUG_PRINTLNTb4b4b4(Ta5d6ff"Ta5d6ffFunction 4: get_sensor_version() SUCCESS: Version = %02XTa5d6ff"Tb4b4b4, Te6edf3vTb4b4b4)Tb4b4b4;
Tff7b72return Te6edf3vTb4b4b4;
Tb4b4b4}
Tffa657float Te6edf3RAK12035_SoilMoistureTff7b72:Tff7b72:Te6edf3get_sensor_temperatureTb4b4b4(Tb4b4b4) T8b949e//Command 05 - (r) 2 bytes
Tb4b4b4{
Tffa657uint8_t Te6edf3bufTb4b4b4[T79c0ff2Tb4b4b4] Tff7b72= Tb4b4b4{T79c0ff0Tb4b4b4}Tb4b4b4;
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3read_rak12035Tb4b4b4(Te6edf3SOILMOISTURESENSOR_GET_TEMPERATURETb4b4b4, Te6edf3bufTb4b4b4, T79c0ff2Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3MESH_DEBUG_PRINTLNTb4b4b4(Ta5d6ff"Ta5d6ffFunction 5: get_temperature() FAIL: Bad data returned = %02X %02XTa5d6ff"Tb4b4b4, Te6edf3bufTb4b4b4[T79c0ff0Tb4b4b4]Tb4b4b4, Te6edf3bufTb4b4b4[T79c0ff1Tb4b4b4]Tb4b4b4)Tb4b4b4;
Tff7b72return Tb4b4b4(Te6edf3bufTb4b4b4[T79c0ff0Tb4b4b4] Tff7b72<Tff7b72< T79c0ff8Tb4b4b4) Tff7b72| Te6edf3bufTb4b4b4[T79c0ff1Tb4b4b4]Tb4b4b4; T8b949e// raw data returned for debugging 0XFFFF is error
Tb4b4b4}
T8b949e// Sensor returns a 16-bit signed integer (°C * 10)
Tffa657int16_t Te6edf3raw Tff7b72= Tb4b4b4(Te6edf3bufTb4b4b4[T79c0ff0Tb4b4b4] Tff7b72<Tff7b72< T79c0ff8Tb4b4b4) Tff7b72| Te6edf3bufTb4b4b4[T79c0ff1Tb4b4b4]Tb4b4b4;
Tffa657float Te6edf3tempC Tff7b72= Te6edf3raw Tff7b72/ T79c0ff10.0fTb4b4b4;
Te6edf3MESH_DEBUG_PRINTLNTb4b4b4(Ta5d6ff"Ta5d6ffFunction 5: get_temperature() SUCCESS: Raw=%04X Temp=%.1f CTa5d6ff"Tb4b4b4, Te6edf3rawTb4b4b4, Te6edf3tempCTb4b4b4)Tb4b4b4;
Tff7b72return Te6edf3tempCTb4b4b4;
Tb4b4b4}
Tffa657bool Te6edf3RAK12035_SoilMoistureTff7b72:Tff7b72:Te6edf3sensor_sleepTb4b4b4(Tb4b4b4) T8b949e//Command 06 - (w) 1 byte
Tb4b4b4{
Tffa657uint8_t Te6edf3tmp Tff7b72= T79c0ff0Tb4b4b4;
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3write_rak12035Tb4b4b4(Te6edf3SOILMOISTURESENSOR_SET_SLEEPTb4b4b4, Tff7b72&Te6edf3tmpTb4b4b4, T79c0ff1Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3MESH_DEBUG_PRINTLNTb4b4b4(Ta5d6ff"Ta5d6ffFunction 6: sensor_sleep() FAIL: Could not send sleep commandTa5d6ff"Tb4b4b4)Tb4b4b4;
Tff7b72return Tffa657falseTb4b4b4;
Tb4b4b4}
Te6edf3MESH_DEBUG_PRINTLNTb4b4b4(Ta5d6ff"Ta5d6ffFunction 6: sensor_sleep() SUCCESS: Sensor acknowledged sleep commandTa5d6ff"Tb4b4b4)Tb4b4b4;
T8b949e// Optional: turn off sensor power AFTER successful sleep command
T8b949e// This has been commented out due to a pin name conflict with the Heltec v3
T8b949e// This will need to be resolved if this function is to be utilized in the future
T8b949e/*
digitalWrite(WB_IO2, LOW);
*/
Tff7b72return Tffa657trueTb4b4b4;
Tb4b4b4}
Tffa657bool Te6edf3RAK12035_SoilMoistureTff7b72:Tff7b72:Te6edf3set_humidity_fullTb4b4b4(Tffa657uint16_t Te6edf3fullTb4b4b4) T8b949e//Command 07 - (w) 2 bytes
Tb4b4b4{
Tffa657uint8_t Te6edf3bufTb4b4b4[T79c0ff2Tb4b4b4]Tb4b4b4;
Te6edf3bufTb4b4b4[T79c0ff0Tb4b4b4] Tff7b72= Tb4b4b4(Te6edf3full Tff7b72>Tff7b72> T79c0ff8Tb4b4b4) Tff7b72& T79c0ff0xFFTb4b4b4; T8b949e// High byte
Te6edf3bufTb4b4b4[T79c0ff1Tb4b4b4] Tff7b72= Te6edf3full Tff7b72& T79c0ff0xFFTb4b4b4; T8b949e// Low byte
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3write_rak12035Tb4b4b4(Te6edf3SOILMOISTURESENSOR_SET_WET_CALTb4b4b4, Te6edf3bufTb4b4b4, T79c0ff2Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3MESH_DEBUG_PRINTLNTb4b4b4(Ta5d6ff"Ta5d6ffFunction 7: set_humidity_full() FAIL: Could not set wet calibration valueTa5d6ff"
Tb4b4b4)Tb4b4b4;
Tff7b72return Tffa657falseTb4b4b4;
Tb4b4b4}
Te6edf3MESH_DEBUG_PRINTLNTb4b4b4(Ta5d6ff"Ta5d6ffFunction 7: set_humidity_full() SUCCESS: New Full = %04XTa5d6ff"Tb4b4b4, Te6edf3fullTb4b4b4)Tb4b4b4;
Tff7b72return Tffa657trueTb4b4b4;
Tb4b4b4}
Tffa657bool Te6edf3RAK12035_SoilMoistureTff7b72:Tff7b72:Te6edf3set_humidity_zeroTb4b4b4(Tffa657uint16_t Te6edf3zeroTb4b4b4) T8b949e//Command 08 - (w) 2 bytes
Tb4b4b4{
Tffa657uint8_t Te6edf3bufTb4b4b4[T79c0ff2Tb4b4b4]Tb4b4b4;
Te6edf3bufTb4b4b4[T79c0ff0Tb4b4b4] Tff7b72= Tb4b4b4(Te6edf3zero Tff7b72>Tff7b72> T79c0ff8Tb4b4b4) Tff7b72& T79c0ff0xFFTb4b4b4; T8b949e// High byte
Te6edf3bufTb4b4b4[T79c0ff1Tb4b4b4] Tff7b72= Te6edf3zero Tff7b72& T79c0ff0xFFTb4b4b4; T8b949e// Low byte
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3write_rak12035Tb4b4b4(Te6edf3SOILMOISTURESENSOR_SET_DRY_CALTb4b4b4, Te6edf3bufTb4b4b4, T79c0ff2Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3MESH_DEBUG_PRINTLNTb4b4b4(Ta5d6ff"Ta5d6ffFunction 8: set_humidity_zero() FAIL: Could not set dry calibration valueTa5d6ff"Tb4b4b4)Tb4b4b4;
Tff7b72return Tffa657falseTb4b4b4;
Tb4b4b4}
Te6edf3MESH_DEBUG_PRINTLNTb4b4b4(Ta5d6ff"Ta5d6ffFunction 8: set_humidity_zero() SUCCESS: New Zero = %04XTa5d6ff"Tb4b4b4, Te6edf3zeroTb4b4b4)Tb4b4b4;
Tff7b72return Tffa657trueTb4b4b4;
Tb4b4b4}
Tffa657uint8_t Te6edf3RAK12035_SoilMoistureTff7b72:Tff7b72:Te6edf3get_sensor_moistureTb4b4b4(Tb4b4b4) T8b949e//Command 09 - (r) 1 byte
Tb4b4b4{
T8b949e// Load calibration values from sensor
Te6edf3_wet_cal Tff7b72= Te6edf3get_humidity_fullTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3_dry_cal Tff7b72= Te6edf3get_humidity_zeroTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3MESH_DEBUG_PRINTLNTb4b4b4(Ta5d6ff"Ta5d6ffFunction 9: get_moisture() - Read from sensor or calculate from capacitanceTa5d6ff"Tb4b4b4)Tb4b4b4;
T8b949e// Read sensor version
Tffa657uint8_t Te6edf3v Tff7b72= Te6edf3get_sensor_versionTb4b4b4(Tb4b4b4)Tb4b4b4;
T8b949e// If version > 2, read moisture directly from the sensor
Tff7b72if Tb4b4b4(Te6edf3v Tff7b72> T79c0ff2Tb4b4b4) Tb4b4b4{
Te6edf3MESH_DEBUG_PRINTLNTb4b4b4(Ta5d6ff"Ta5d6ffVersion > 02 - Reading moisture directly from sensorTa5d6ff"Tb4b4b4)Tb4b4b4;
Tffa657uint8_t Te6edf3moisture Tff7b72= Te6edf3get_sensor_humidTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3MESH_DEBUG_PRINTLNTb4b4b4(Ta5d6ff"Ta5d6ffget_moisture() Direct Read = %d%%Ta5d6ff"Tb4b4b4, Te6edf3moistureTb4b4b4)Tb4b4b4;
Tff7b72return Te6edf3moistureTb4b4b4;
Tb4b4b4}
T8b949e// Otherwise calculate moisture from capacitance
Te6edf3MESH_DEBUG_PRINTLNTb4b4b4(Ta5d6ff"Ta5d6ffCalculating moisture from capacitanceTa5d6ff"Tb4b4b4)Tb4b4b4;
Tffa657uint16_t Te6edf3cap Tff7b72= Te6edf3get_sensor_capacitanceTb4b4b4(Tb4b4b4)Tb4b4b4;
T8b949e// Clamp capacitance between calibration points
Tff7b72if Tb4b4b4(Te6edf3_dry_cal Tff7b72< Te6edf3_wet_calTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3cap Tff7b72<Tff7b72= Te6edf3_dry_calTb4b4b4) Te6edf3cap Tff7b72= Te6edf3_dry_calTb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3cap Tff7b72>Tff7b72= Te6edf3_wet_calTb4b4b4) Te6edf3cap Tff7b72= Te6edf3_wet_calTb4b4b4;
Tffa657float Te6edf3pct Tff7b72= Tb4b4b4(Te6edf3_wet_cal Tff7b72- Te6edf3capTb4b4b4) Tff7b72* T79c0ff100.0f Tff7b72/ Tb4b4b4(Te6edf3_wet_cal Tff7b72- Te6edf3_dry_calTb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3pct Tff7b72> T79c0ff100.0fTb4b4b4) Te6edf3pct Tff7b72= T79c0ff100.0fTb4b4b4;
Te6edf3MESH_DEBUG_PRINTLNTb4b4b4(Ta5d6ff"Ta5d6ffget_moisture Case 1() Calculated = %d%%Ta5d6ff"Tb4b4b4, Tb4b4b4(Tffa657uint8_tTb4b4b4)Te6edf3pctTb4b4b4)Tb4b4b4;
Tff7b72return Tb4b4b4(Tffa657uint8_tTb4b4b4)Te6edf3pctTb4b4b4;
Tb4b4b4} Tff7b72else Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3cap Tff7b72>Tff7b72= Te6edf3_dry_calTb4b4b4) Te6edf3cap Tff7b72= Te6edf3_dry_calTb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3cap Tff7b72<Tff7b72= Te6edf3_wet_calTb4b4b4) Te6edf3cap Tff7b72= Te6edf3_wet_calTb4b4b4;
Tffa657float Te6edf3pct Tff7b72= Tb4b4b4(Te6edf3_dry_cal Tff7b72- Te6edf3capTb4b4b4) Tff7b72* T79c0ff100.0f Tff7b72/ Tb4b4b4(Te6edf3_dry_cal Tff7b72- Te6edf3_wet_calTb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3pct Tff7b72> T79c0ff100.0fTb4b4b4) Te6edf3pct Tff7b72= T79c0ff100.0fTb4b4b4;
Te6edf3MESH_DEBUG_PRINTLNTb4b4b4(Ta5d6ff"Ta5d6ffget_moisture Case 2() Calculated = %d%%Ta5d6ff"Tb4b4b4, Tb4b4b4(Tffa657uint8_tTb4b4b4)Te6edf3pctTb4b4b4)Tb4b4b4;
Tff7b72return Tb4b4b4(Tffa657uint8_tTb4b4b4)Te6edf3pctTb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tffa657uint8_t Te6edf3RAK12035_SoilMoistureTff7b72:Tff7b72:Te6edf3get_sensor_humidTb4b4b4(Tb4b4b4) T8b949e//Command 09 - (r) 1 byte
Tb4b4b4{
Tffa657uint8_t Te6edf3moisture Tff7b72= T79c0ff0Tb4b4b4;
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3read_rak12035Tb4b4b4(Te6edf3SOILMOISTURESENSOR_GET_MOISTURETb4b4b4, Tff7b72&Te6edf3moistureTb4b4b4, T79c0ff1Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3MESH_DEBUG_PRINTLNTb4b4b4(Ta5d6ff"Ta5d6ffFunction 9: get_sensor_humid() FAIL: Bad data returned = %02XTa5d6ff"Tb4b4b4, Te6edf3moistureTb4b4b4)Tb4b4b4;
Tff7b72return Te6edf3moistureTb4b4b4; T8b949e// raw fallback
Tb4b4b4}
Te6edf3MESH_DEBUG_PRINTLNTb4b4b4(Ta5d6ff"Ta5d6ffFunction 9: get_sensor_humid() SUCCESS: Moisture = %d%%Ta5d6ff"Tb4b4b4,Te6edf3moistureTb4b4b4)Tb4b4b4;
Tff7b72return Te6edf3moistureTb4b4b4;
Tb4b4b4}
Tffa657uint16_t Te6edf3RAK12035_SoilMoistureTff7b72:Tff7b72:Te6edf3get_humidity_fullTb4b4b4(Tb4b4b4) T8b949e//Command 0A - (r) 2 bytes
Tb4b4b4{
Tffa657uint8_t Te6edf3bufTb4b4b4[T79c0ff2Tb4b4b4] Tff7b72= Tb4b4b4{T79c0ff0Tb4b4b4}Tb4b4b4;
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3read_rak12035Tb4b4b4(Te6edf3SOILMOISTURESENSOR_GET_WET_CALTb4b4b4, Te6edf3bufTb4b4b4, T79c0ff2Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3MESH_DEBUG_PRINTLNTb4b4b4(Ta5d6ff"Ta5d6ffFunction A: get_humidity_full() FAIL: Bad data returned = %02X%02XTa5d6ff"Tb4b4b4, Te6edf3bufTb4b4b4[T79c0ff0Tb4b4b4]Tb4b4b4, Te6edf3bufTb4b4b4[T79c0ff1Tb4b4b4]Tb4b4b4)Tb4b4b4;
Tff7b72return T79c0ff0xFFFFTb4b4b4; T8b949e// error indicator
Tb4b4b4}
Tffa657uint16_t Te6edf3full Tff7b72= Tb4b4b4(Te6edf3bufTb4b4b4[T79c0ff0Tb4b4b4] Tff7b72<Tff7b72< T79c0ff8Tb4b4b4) Tff7b72| Te6edf3bufTb4b4b4[T79c0ff1Tb4b4b4]Tb4b4b4;
Te6edf3MESH_DEBUG_PRINTLNTb4b4b4(Ta5d6ff"Ta5d6ffFunction A: get_humidity_full() SUCCESS: Full = %04X = %dTa5d6ff"Tb4b4b4, Te6edf3fullTb4b4b4, Te6edf3fullTb4b4b4)Tb4b4b4;
Tff7b72return Te6edf3fullTb4b4b4;
Tb4b4b4}
Tffa657uint16_t Te6edf3RAK12035_SoilMoistureTff7b72:Tff7b72:Te6edf3get_humidity_zeroTb4b4b4(Tb4b4b4) T8b949e//Command 0B - 2 bytes
Tb4b4b4{
Tffa657uint8_t Te6edf3bufTb4b4b4[T79c0ff2Tb4b4b4] Tff7b72= Tb4b4b4{T79c0ff0Tb4b4b4}Tb4b4b4;
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3read_rak12035Tb4b4b4(Te6edf3SOILMOISTURESENSOR_GET_DRY_CALTb4b4b4, Te6edf3bufTb4b4b4, T79c0ff2Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3MESH_DEBUG_PRINTLNTb4b4b4(Ta5d6ff"Ta5d6ffFunction B: get_humidity_zero() FAIL: Bad data returned = %02X%02XTa5d6ff"Tb4b4b4, Te6edf3bufTb4b4b4[T79c0ff0Tb4b4b4]Tb4b4b4, Te6edf3bufTb4b4b4[T79c0ff1Tb4b4b4]Tb4b4b4)Tb4b4b4;
Tff7b72return T79c0ff0xFFFFTb4b4b4; T8b949e// error indicator
Tb4b4b4}
Tffa657uint16_t Te6edf3zero Tff7b72= Tb4b4b4(Te6edf3bufTb4b4b4[T79c0ff0Tb4b4b4] Tff7b72<Tff7b72< T79c0ff8Tb4b4b4) Tff7b72| Te6edf3bufTb4b4b4[T79c0ff1Tb4b4b4]Tb4b4b4;
Te6edf3MESH_DEBUG_PRINTLNTb4b4b4(Ta5d6ff"Ta5d6ffFunction B: get_humidity_zero() SUCCESS: Zero = %04X = %dTa5d6ff"Tb4b4b4, Te6edf3zeroTb4b4b4, Te6edf3zeroTb4b4b4)Tb4b4b4;
Tff7b72return Te6edf3zeroTb4b4b4;
Tb4b4b4}
T8b949e/*------------------------------------------------------------------------------------------*
* getEvent() - High-level function to read both moisture and temperature in one call. *
*------------------------------------------------------------------------------------------*
* This function reads the moisture percentage and temperature from the sensor and returns *
* them via output parameters. This may be used for the telemetry delivery in the MeshCore *
* firmware, with a single function to get all sensor data. *
* *
* The function returns true if both readings were successfully obtained, or false if any *
* error occurred during I2C communication. *
* *
* This function is currently not used *
*------------------------------------------------------------------------------------------*/
Tffa657bool Te6edf3RAK12035_SoilMoistureTff7b72:Tff7b72:Te6edf3getEventTb4b4b4(Tffa657uint8_t Tff7b72*Te6edf3humidityTb4b4b4, Tffa657uint16_t Tff7b72*Te6edf3tempTb4b4b4)
Tb4b4b4{
T8b949e// Read moisture (0-100%)
Tffa657uint8_t Te6edf3moist Tff7b72= Te6edf3get_sensor_moistureTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3moist Tff7b72=Tff7b72= T79c0ff0xFFTb4b4b4) T8b949e//error indicator
Tff7b72return Tffa657falseTb4b4b4;
Te6edf3MESH_DEBUG_PRINTLNTb4b4b4(Ta5d6ff"Ta5d6ffgetEvent() - Humidity = %dTa5d6ff"Tb4b4b4, Te6edf3moistTb4b4b4)Tb4b4b4;
Tff7b72*Te6edf3humidity Tff7b72= Te6edf3moistTb4b4b4;
T8b949e//Read temperature (degrees C)
Tffa657uint16_t Te6edf3t Tff7b72= Te6edf3get_sensor_temperatureTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3t Tff7b72=Tff7b72= T79c0ff0XFFFFTb4b4b4) T8b949e// error indicator
Tff7b72return Tffa657falseTb4b4b4;
Tff7b72*Te6edf3temp Tff7b72= Te6edf3tTb4b4b4;
Te6edf3MESH_DEBUG_PRINTLNTb4b4b4(Ta5d6ff"Ta5d6ffgetEvent() - Temperature = %dTa5d6ff"Tb4b4b4, Te6edf3tTb4b4b4)Tb4b4b4;
Tff7b72return Tffa657trueTb4b4b4;
Tb4b4b4}
T8b949e/*------------------------------------------------------------------------------------------*
* Sensor Power Management and Reset Routines
*
* These routines manage the power and reset state of the sensor. The sensor_on() routine is
* designed to power on the sensor and wait for it to become responsive, while the reset()
* routine toggles the reset pin and waits for the sensor to respond with a valid version.
*
* They are for a future sensor power management function.
*------------------------------------------------------------------------------------------*/
Tffa657bool Te6edf3RAK12035_SoilMoistureTff7b72:Tff7b72:Te6edf3sensor_onTb4b4b4(Tb4b4b4)
Tb4b4b4{
Tffa657uint8_t Te6edf3dataTb4b4b4;
T8b949e// This has been commented out due to a pin name conflict with the Heltec v3
T8b949e// This will need to be resolved if this function is to be utilized in the future
T8b949e/*
pinMode(WB_IO2, OUTPUT);
digitalWrite(WB_IO2, HIGH); //Turn on Sensor Power
pinMode(WB_IO4, OUTPUT); //Set IO4 Pin to Output (connected to *reset on sensor)
digitalWrite(WB_IO4, LOW); //*reset - Reset the Sensor
delay(1); //Wait for the minimum *reset, 1mS is longer than required minimum
digitalWrite(WB_IO4, HIGH); //Deassert Reset
delay(10); // Wait for the sensor code to complete initialization
*/
Tffa657uint8_t Te6edf3v Tff7b72= T79c0ff0Tb4b4b4;
Tffa657uint32_t Te6edf3timeout Tff7b72= Te6edf3millisTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72while Tb4b4b4(Tb4b4b4(Tff7b72!Te6edf3query_sensorTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4) T8b949e//Wait for sensor to respond to I2C commands,
Tb4b4b4{ T8b949e//indicating it is ready
Tff7b72if Tb4b4b4(Tb4b4b4(Te6edf3millisTb4b4b4(Tb4b4b4) Tff7b72- Te6edf3timeoutTb4b4b4) Tff7b72> T79c0ff50Tb4b4b4)Tb4b4b4{ T8b949e//0.5 second timeout for sensor to respond
Te6edf3MESH_DEBUG_PRINTLNTb4b4b4(Ta5d6ff"Ta5d6ffreset() - Timeout, no response from I2C commandsTa5d6ff"Tb4b4b4)Tb4b4b4;
Tff7b72return Tffa657falseTb4b4b4;
Tb4b4b4}
Tff7b72else Tb4b4b4{
Te6edf3delayTb4b4b4(T79c0ff10Tb4b4b4)Tb4b4b4; T8b949e//delay 10mS
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tffa657bool Te6edf3RAK12035_SoilMoistureTff7b72:Tff7b72:Te6edf3resetTb4b4b4(Tb4b4b4)
Tb4b4b4{
T8b949e// This function is for a future Sensor Power Management function.
T8b949e// When power is reapplied this will reset the sensor and wait for it to respond
T8b949e// with a valid version.
T8b949e//
T8b949e// The Atmel 8495 Microcoltroller: Reset input. A low level on this pin for longer than
T8b949e// the minimum pulse length will generate a reset, even if the clock is not
T8b949e// running and provided the reset pin has not been disabled. The minimum pulse length is
T8b949e// given in Table 25-5 on page 240. 2000ns = .002mS
T8b949e// Shorter pulses are not guaranteed to generate a reset.
T8b949e//
T8b949e// Power is never removed so the Sensor reset was removed and is not needed,
T8b949e// But might be needed if power is ever switched off. Here is tested code.
T8b949e// This has been commented out due to a pin name conflict with the Heltec v3
T8b949e// This will need to be resolved if this function is to be utilized in the future
T8b949e/*
pinMode(WB_IO4, OUTPUT); //Set IO4 Pin to Output (connected to *reset on sensor)
MESH_DEBUG_PRINTLN("Assert *reset (Low) for 1 mS");
digitalWrite(WB_IO4, LOW); //Reset the Sensor
delay(1); //Wait for the minimum *reset, 1mS is longer than required minimum
MESH_DEBUG_PRINTLN("reset() - De-assert *reset (High)");
digitalWrite(WB_IO4, HIGH); // Deassert Reset
*/
Te6edf3MESH_DEBUG_PRINTLNTb4b4b4(Ta5d6ff"Ta5d6ffreset() - Begin poling in 100mS intervals for a non-zero versionTa5d6ff"Tb4b4b4)Tb4b4b4;
Tffa657uint32_t Te6edf3start_time Tff7b72= Te6edf3millisTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3MESH_DEBUG_PRINTLNTb4b4b4(Ta5d6ff"Ta5d6ffreset() - Timeout, Start Time: %d millisecondsTa5d6ff"Tb4b4b4, Te6edf3start_timeTb4b4b4)Tb4b4b4;
Tff7b72const Tffa657uint32_t Te6edf3timeout_ms Tff7b72= T79c0ff500Tb4b4b4; T8b949e// Wait for 0.5 seconds
Tffa657uint32_t Te6edf3start Tff7b72= Te6edf3millisTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72while Tb4b4b4(Tffa657trueTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3query_sensorTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3MESH_DEBUG_PRINTLNTb4b4b4(Ta5d6ff"Ta5d6ffreset() - First Pass, Sensor responded with valid versionTa5d6ff"Tb4b4b4)Tb4b4b4;
Tffa657uint32_t Te6edf3stop_time Tff7b72= Te6edf3millisTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3MESH_DEBUG_PRINTLNTb4b4b4(Ta5d6ff"Ta5d6ffreset() - Timeout, Stop Time: %d mSTa5d6ff"Tb4b4b4, Te6edf3stop_timeTb4b4b4)Tb4b4b4;
Te6edf3MESH_DEBUG_PRINTLNTb4b4b4(Ta5d6ff"Ta5d6ffreset() - Timeout, Duration: %d mSTa5d6ff"Tb4b4b4, Tb4b4b4(Te6edf3stop_time Tff7b72- Te6edf3start_timeTb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72return Tffa657trueTb4b4b4;
Tb4b4b4}
Tff7b72if Tb4b4b4(Te6edf3millisTb4b4b4(Tb4b4b4) Tff7b72- Te6edf3start Tff7b72> Te6edf3timeout_msTb4b4b4) Tb4b4b4{
Te6edf3MESH_DEBUG_PRINTLNTb4b4b4(Ta5d6ff"Ta5d6ffreset() - Timeout waiting for valid sensor versionTa5d6ff"Tb4b4b4)Tb4b4b4;
Tffa657uint32_t Te6edf3stop_time Tff7b72= Te6edf3millisTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3MESH_DEBUG_PRINTLNTb4b4b4(Ta5d6ff"Ta5d6ffreset() - Timeout, Stop Time: %d mSTa5d6ff"Tb4b4b4, Te6edf3stop_timeTb4b4b4)Tb4b4b4;
Te6edf3MESH_DEBUG_PRINTLNTb4b4b4(Ta5d6ff"Ta5d6ffreset() - Timeout, Duration: %d mSTa5d6ff"Tb4b4b4, Tb4b4b4(Te6edf3stop_time Tff7b72- Te6edf3start_timeTb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72return Tffa657falseTb4b4b4;
Tb4b4b4}
Te6edf3delayTb4b4b4(T79c0ff100Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tffa657bool Te6edf3RAK12035_SoilMoistureTff7b72:Tff7b72:Te6edf3query_sensorTb4b4b4(Tb4b4b4)
Tb4b4b4{
Tffa657uint8_t Te6edf3v Tff7b72= T79c0ff0Tb4b4b4;
Te6edf3v Tff7b72= Te6edf3get_sensor_versionTb4b4b4(Tb4b4b4)Tb4b4b4;
T8b949e// Treat 0x00 and 0xFF as invalid / bootloader / garbage
Tff7b72if Tb4b4b4(Te6edf3v Tff7b72=Tff7b72= T79c0ff0x00 Tff7b72|Tff7b72| Te6edf3v Tff7b72=Tff7b72= T79c0ff0xFFTb4b4b4) Tb4b4b4{
Te6edf3MESH_DEBUG_PRINTLNTb4b4b4(Ta5d6ff"Ta5d6ffquery_sensor() FAIL: Version value invalid: %02XTa5d6ff"Tb4b4b4, Te6edf3vTb4b4b4)Tb4b4b4;
Tff7b72return Tffa657falseTb4b4b4;
Tb4b4b4}
Te6edf3MESH_DEBUG_PRINTLNTb4b4b4(Ta5d6ff"Ta5d6ffquery_sensor() SUCCESS: Sensor Present, Version = %02XTa5d6ff"Tb4b4b4, Te6edf3vTb4b4b4)Tb4b4b4;
Tff7b72return Tffa657trueTb4b4b4;
Tb4b4b4}
T8b949e/*------------------------------------------------------------------------------------------*
* Below are the low-level I2C read and write functions. These handle the actual
* communication with the sensor registers. The higher-level functions call these
* to perform specific tasks.
*------------------------------------------------------------------------------------------*/
Tffa657bool Te6edf3RAK12035_SoilMoistureTff7b72:Tff7b72:Te6edf3read_rak12035Tb4b4b4(Tffa657uint8_t Te6edf3cmdTb4b4b4, Tffa657uint8_t Tff7b72*Te6edf3dataTb4b4b4, Tffa657uint8_t Te6edf3lengthTb4b4b4)
Tb4b4b4{
Te6edf3_i2cTff7b72-Tff7b72>Te6edf3beginTransmissionTb4b4b4(Te6edf3_addrTb4b4b4)Tb4b4b4;
Te6edf3_i2cTff7b72-Tff7b72>Te6edf3writeTb4b4b4(Te6edf3cmdTb4b4b4)Tb4b4b4; T8b949e// <-- COMMAND, not register index
Tff7b72if Tb4b4b4(Te6edf3_i2cTff7b72-Tff7b72>Te6edf3endTransmissionTb4b4b4(Tb4b4b4) Tff7b72!Tff7b72= T79c0ff0Tb4b4b4)
Tff7b72return Tffa657falseTb4b4b4;
Te6edf3delayTb4b4b4(T79c0ff20Tb4b4b4)Tb4b4b4;
Tffa657int Te6edf3received Tff7b72= Te6edf3_i2cTff7b72-Tff7b72>Te6edf3requestFromTb4b4b4(Te6edf3_addrTb4b4b4, Te6edf3lengthTb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3received Tff7b72!Tff7b72= Te6edf3lengthTb4b4b4)
Tff7b72return Tffa657falseTb4b4b4;
Tff7b72for Tb4b4b4(Tffa657int Te6edf3i Tff7b72= T79c0ff0Tb4b4b4; Te6edf3i Tff7b72< Te6edf3lengthTb4b4b4; Te6edf3iTff7b72+Tff7b72+Tb4b4b4)
Te6edf3dataTb4b4b4[Te6edf3iTb4b4b4] Tff7b72= Te6edf3_i2cTff7b72-Tff7b72>Te6edf3readTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72return Tffa657trueTb4b4b4;
Tb4b4b4}
Tffa657bool Te6edf3RAK12035_SoilMoistureTff7b72:Tff7b72:Te6edf3write_rak12035Tb4b4b4(Tffa657uint8_t Te6edf3cmdTb4b4b4, Tffa657uint8_t Tff7b72*Te6edf3dataTb4b4b4, Tffa657uint8_t Te6edf3lengthTb4b4b4)
Tb4b4b4{
Te6edf3_i2cTff7b72-Tff7b72>Te6edf3beginTransmissionTb4b4b4(Te6edf3_addrTb4b4b4)Tb4b4b4;
Te6edf3_i2cTff7b72-Tff7b72>Te6edf3writeTb4b4b4(Te6edf3cmdTb4b4b4)Tb4b4b4; T8b949e// <-- COMMAND, not register index
Tff7b72for Tb4b4b4(Tffa657uint8_t Te6edf3i Tff7b72= T79c0ff0Tb4b4b4; Te6edf3i Tff7b72< Te6edf3lengthTb4b4b4; Te6edf3iTff7b72+Tff7b72+Tb4b4b4)
Te6edf3_i2cTff7b72-Tff7b72>Te6edf3writeTb4b4b4(Te6edf3dataTb4b4b4[Te6edf3iTb4b4b4]Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3_i2cTff7b72-Tff7b72>Te6edf3endTransmissionTb4b4b4(Tb4b4b4) Tff7b72!Tff7b72= T79c0ff0Tb4b4b4)
Tff7b72return Tffa657falseTb4b4b4;
Te6edf3delayTb4b4b4(T79c0ff20Tb4b4b4)Tb4b4b4;
Tff7b72return Tffa657trueTb4b4b4;
Tb4b4b4}
Served by rngit 1.5.4 - Generated in 0.08s